diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 5b9b37f..6a6a62b 100644
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
*************** postgres=# SELECT * FROM pg_xlogfile_nam
*** 13187,13192 ****
--- 13187,13198 ----
pg_total_relation_size
+
+ pg_table_size
+
+
+ pg_indexes_size
+
Database Object Size Functions
*************** postgres=# SELECT * FROM pg_xlogfile_nam
*** 13259,13270 ****
pg_total_relation_size(regclass)
bigint
Total disk space used by the table with the specified OID or name,
! including indexes and TOAST> data
--- 13265,13297 ----
+ pg_table_size(regclass)
+
+ bigint
+
+ Total disk space with TOAST used by the table with the specified OID or name
+ without user defined indexes. This also includes the size of free space maps
+ and visibility maps attached to a table.
+
+
+
+
+ pg_indexes_size(regclass)
+
+ bigint
+
+ Total disk space used by user defined indexes attached to the table with the
+ specified OID or name.
+
+
+
+
pg_total_relation_size(regclass)
bigint
Total disk space used by the table with the specified OID or name,
! including indexes and TOAST> data.
*************** postgres=# SELECT * FROM pg_xlogfile_nam
*** 13291,13297 ****
Free Space Map (see ) associated with the
relation. Specifying 'vm' returns the size of the
Visibility Map (see ) associated with the
! relation.
--- 13318,13331 ----
Free Space Map (see ) associated with the
relation. Specifying 'vm' returns the size of the
Visibility Map (see ) associated with the
! relation. The total storage consumed by a table with all attached
! forks and TOAST data can be retrieved by pg_table_size>.
!
!
!
! pg_indexes_size> accepts the OID or name of a table and
! returns the total disk size of all user defined indexes or keys of
! the given table.
*************** postgres=# SELECT * FROM pg_xlogfile_nam
*** 13303,13309 ****
pg_total_relation_size> accepts the OID or name of a
table or toast table, and returns the size in bytes of the data
! and all associated indexes and toast tables.
--- 13337,13345 ----
pg_total_relation_size> accepts the OID or name of a
table or toast table, and returns the size in bytes of the data
! and all associated indexes and toast tables. This function
! is a shorthand version of pg_table_size
! + pg_indexes_size.
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index a280ff8..8d45992 100644
*** a/src/backend/utils/adt/dbsize.c
--- b/src/backend/utils/adt/dbsize.c
*************** pg_relation_size(PG_FUNCTION_ARGS)
*** 302,355 ****
PG_RETURN_INT64(size);
}
/*
! * Compute the on-disk size of files for the relation according to the
! * stat function, including heap data, index data, and toast data.
*/
static int64
! calculate_total_relation_size(Oid Relid)
{
! Relation heapRel;
! Oid toastOid;
! int64 size;
! ListCell *cell;
! ForkNumber forkNum;
!
! heapRel = relation_open(Relid, AccessShareLock);
! toastOid = heapRel->rd_rel->reltoastrelid;
- /* Get the heap size */
size = 0;
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
! size += calculate_relation_size(&(heapRel->rd_node), forkNum);
! /* Include any dependent indexes */
! if (heapRel->rd_rel->relhasindex)
{
! List *index_oids = RelationGetIndexList(heapRel);
foreach(cell, index_oids)
{
Oid idxOid = lfirst_oid(cell);
! Relation iRel;
!
! iRel = relation_open(idxOid, AccessShareLock);
!
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
! size += calculate_relation_size(&(iRel->rd_node), forkNum);
!
! relation_close(iRel, AccessShareLock);
}
list_free(index_oids);
}
! /* Recursively include toast table (and index) size */
! if (OidIsValid(toastOid))
! size += calculate_total_relation_size(toastOid);
! relation_close(heapRel, AccessShareLock);
return size;
}
--- 302,437 ----
PG_RETURN_INT64(size);
}
+ static int64
+ calculate_toast_table_size(Oid toastrelid)
+ {
+ Relation toastRel;
+ Relation toastIdxRel;
+ ForkNumber forkNum;
+ int64 size;
+
+ size = 0;
+ toastRel = relation_open(toastrelid, AccessShareLock);
+
+ /* toast heap size, including FSM and VM size */
+ for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ size += calculate_relation_size(&(toastRel->rd_node), forkNum);
+
+ /* toast index size, including FSM and VM size */
+ toastIdxRel = relation_open(toastRel->rd_rel->reltoastidxid, AccessShareLock);
+ for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ size += calculate_relation_size(&(toastIdxRel->rd_node), forkNum);
+
+ relation_close(toastRel, AccessShareLock);
+ relation_close(toastIdxRel, AccessShareLock);
+
+ PG_RETURN_INT64(size);
+ }
/*
! * Calculates the size of a given table,
! * including TOAST table and its index, FSM
! * and VM.
*/
static int64
! calculate_table_size(Oid relOid)
{
! Relation rel;
! ForkNumber forkNum;
! int64 size;
size = 0;
+ rel = relation_open(relOid, AccessShareLock);
+
+ /*
+ * heap size, including FSM and VM
+ */
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
! size += calculate_relation_size(&(rel->rd_node), forkNum);
! /*
! * Size of toast relation
! */
! if (OidIsValid(rel->rd_rel->reltoastrelid)) {
! size += calculate_toast_table_size(rel->rd_rel->reltoastrelid);
! }
!
! relation_close(rel, AccessShareLock);
! PG_RETURN_INT64(size);
! }
!
! static int64
! calculate_indexes_size(Oid relOid)
! {
! Relation rel;
! int64 size;
!
! size = 0;
! rel = relation_open(relOid, AccessShareLock);
!
! /*
! * Aggregate all indexes on the given relation
! */
! if (rel->rd_rel->relhasindex)
{
! List *index_oids = RelationGetIndexList(rel);
! ListCell *cell;
foreach(cell, index_oids)
{
Oid idxOid = lfirst_oid(cell);
! Relation idxRel;
! ForkNumber forkNum;
!
! idxRel = relation_open(idxOid, AccessShareLock);
!
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
! size += calculate_relation_size(&(idxRel->rd_node), forkNum);
!
! relation_close(idxRel, AccessShareLock);
}
list_free(index_oids);
}
+
+ relation_close(rel, AccessShareLock);
+ PG_RETURN_INT64(size);
+ }
! Datum
! pg_table_size(PG_FUNCTION_ARGS)
! {
! Oid relOid = PG_GETARG_OID(0);
! PG_RETURN_INT64(calculate_table_size(relOid));
! }
! Datum
! pg_indexes_size(PG_FUNCTION_ARGS)
! {
! Oid relOid = PG_GETARG_OID(0);
! PG_RETURN_INT64(calculate_indexes_size(relOid));
! }
!
! /*
! * Compute the on-disk size of files for the relation according to the
! * stat function, including heap data, index data, and toast data.
! */
! static int64
! calculate_total_relation_size(Oid Relid)
! {
! int64 size;
!
! /*
! * Aggregate the table size, this includes size of
! * the heap, toast and toast index with free space
! * and visibility map
! */
! size = calculate_table_size(Relid);
!
! /*
! * Get size of all attached indexes as well
! */
! size += calculate_indexes_size(Relid);
return size;
}
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index a8efed9..756b659 100644
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
*************** DATA(insert OID = 2286 ( pg_total_relati
*** 3702,3707 ****
--- 3702,3711 ----
DESCR("total disk space usage for the specified table and associated indexes and toast tables");
DATA(insert OID = 2288 ( pg_size_pretty PGNSP PGUID 12 1 0 0 f f f t f v 1 0 25 "20" _null_ _null_ _null_ _null_ pg_size_pretty _null_ _null_ _null_ ));
DESCR("convert a long int to a human readable text using size units");
+ DATA(insert OID = 2997 ( pg_table_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_table_size _null_ _null_ _null_ ));
+ DESCR("disk space usage including TOAST, free space and visibility map for the specified table");
+ DATA(insert OID = 2998 ( pg_indexes_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_indexes_size _null_ _null_ _null_ ));
+ DESCR("disk space usage of all indexes attached to the specified table");
DATA(insert OID = 2316 ( postgresql_fdw_validator PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "1009 26" _null_ _null_ _null_ _null_ postgresql_fdw_validator _null_ _null_ _null_));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 91411a4..72e9ed0 100644
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
*************** extern Datum pg_database_size_name(PG_FU
*** 433,438 ****
--- 433,440 ----
extern Datum pg_relation_size(PG_FUNCTION_ARGS);
extern Datum pg_total_relation_size(PG_FUNCTION_ARGS);
extern Datum pg_size_pretty(PG_FUNCTION_ARGS);
+ extern Datum pg_table_size(PG_FUNCTION_ARGS);
+ extern Datum pg_indexes_size(PG_FUNCTION_ARGS);
/* genfile.c */
extern Datum pg_stat_file(PG_FUNCTION_ARGS);